package io.renren.mqtt;

import com.alibaba.fastjson.JSONObject;
import io.renren.modules.wmstate.dao.WeldingmachineStateDao;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.core.MessageProducer;
import org.springframework.integration.mqtt.core.DefaultMqttPahoClientFactory;
import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter;
import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.EnableRetry;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.scheduling.annotation.Scheduled;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Slf4j
@Configuration
@EnableRetry
public class UpdateKtTwoConfiguration {

    @Autowired
    UpdateWmHandler updateWmHandler;

    @Autowired
    WeldingmachineStateDao weldingmachineStateDao;
    static String clientId = UUID.randomUUID().toString();

    private static final String URL = "tcp://10.142.3.129:1883";
//    private static final String URL = "tcp://weld.cmhijs.cn:1883";
    private static final String CLIENT_ID = clientId;
//焊机端口
    private static final String TOPIC4 = "/gw/acrelHW/AWT100/data/#";

    private static final int MAX_RETRY_ATTEMPTS = 5;
    private int retryCount = 0;

    @Bean
    public MqttConnectOptions mqttConnectOptions(){
        MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
        mqttConnectOptions.setServerURIs(new String[]{URL});
        mqttConnectOptions.setConnectionTimeout(100);
        mqttConnectOptions.setAutomaticReconnect(true); // 设置自动重连
        mqttConnectOptions.setCleanSession(true);
        return mqttConnectOptions;
    }

    @Bean
    public MqttPahoClientFactory mqttClientFactory() {
        DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
        factory.setConnectionOptions(mqttConnectOptions());
        return factory;
    }


    @Bean
    public MessageChannel mqttInputChannel4() {
        return new DirectChannel();
    }


    @Value("${mqtt.enable}")
    private boolean mqttEnabled; // 通过配置文件注入是否启用 MQTT 订阅的值


    @Bean
    @Retryable(value = {MqttException.class}, maxAttempts = MAX_RETRY_ATTEMPTS, backoff = @Backoff(delay = 5000))
    public MessageProducer inbound4() {
        if (mqttEnabled) {
            CustomMqttPahoMessageDrivenChannelAdapter adapter =
                    new CustomMqttPahoMessageDrivenChannelAdapter(CLIENT_ID + "_4", mqttClientFactory(), TOPIC4);
            adapter.setCompletionTimeout(50000);
            adapter.setConverter(new DefaultPahoMessageConverter());
            adapter.setQos(0);
            adapter.setOutputChannel(mqttInputChannel4());
            return adapter;
        } else {
            // 如果 MQTT 订阅被禁用，返回一个空的 MessageProducer
            return null;
        }
    }





    @Recover
    public void recover(MqttException ex) {
        if (retryCount < MAX_RETRY_ATTEMPTS) {
            log.error("连接到 MQTT 代理失败。正在进行第 " + (retryCount + 1) + " 次重试...", ex);
            retryCount++;
        } else {
            log.error("连接到 MQTT 代理失败，重试次数已达到上限。执行定时任务进行重试或通知相关人员。", ex);
            // 这里您可以执行定时任务进行重试，或者触发通知机制
            // 例如：scheduleRetry();
        }
    }

    @Scheduled(fixedDelay = 60000) // 每隔一分钟执行一次定时任务
    public void scheduleRetry() {
        if (retryCount >= MAX_RETRY_ATTEMPTS) {
            // 在定时任务中进行重试或者执行通知机制
            log.info("执行定时任务进行 MQTT 连接重试...");
            // 重置重试计数器
            retryCount = 0;
            // 进行新的连接尝试，您可以调用相关方法重新尝试连接
            // retryConnection();
        }
    }







    @ServiceActivator(inputChannel = "mqttInputChannel4")
    public void handleMessage4(Message<?> message) throws Exception {
        //解析messsage
        String msg = (String) message.getPayload();

        //定义一个常量120，用于修改电流I的值
        final int a = 120;
        JSONObject jsonObject = JSONObject.parseObject(msg);

        //msg:{"type":"data","time":"20230829112715","datatime":"20230829112700","gwSN":"12304178610198","meterSN":"12304178610326","meterName":"DJSF1352RN","meterStatus":"normal","ch":0,"U":0,"I":1.014,"P":0,"TEMP":34.3,"EPI":14.042,"EPE":0,"PT":1,"CT":5}
        String gwSN = jsonObject.getString("gwSN");

        // 根据wmNo和gatew查找对应关系
        Integer wmId = findCorrespondingValue(gwSN);

        //电压
        Double U = jsonObject.getDouble("U");

        //电流
        Double I = jsonObject.getDouble("I");

        // 检查电压U的值，如果不为0，则修改电流I的值
        if (U != 0) {
            I = I * a;
        }

        //获取温度，已废弃
        Integer TEMP = jsonObject.getInteger("TEMP");

//        System.out.println("gwSN:"+gwSN+" U:"+U+" I:"+I+" TEMP:"+TEMP);



        //根据gwSN将U、I、TEMP更新到数据库
        weldingmachineStateDao.updateWmState(U,I,TEMP,gwSN);
    }








    private Integer findCorrespondingValue(String gwSN) {
        // 在这里实现查找对应关系的逻辑，使用您提供的对应关系数据
        Map<String, Integer> correspondenceMap = getCorrespondenceMap(); // 获取对应关系的Map

        // 根据gatew查找对应的值
        return correspondenceMap.get(gwSN);
    }






    // 您可以将对应关系数据放在这个方法中，或者从其他地方获取
    private Map<String, Integer> getCorrespondenceMap() {
        Map<String, Integer> correspondenceMap = new HashMap<>();
        // 添加对应关系数据到Map

            correspondenceMap.put("12304178610234",1);
            correspondenceMap.put("12304178610225",2);
            correspondenceMap.put("12304178610205",3);
            correspondenceMap.put("12304178610163",4);
            correspondenceMap.put("12304178610216",5);
            correspondenceMap.put("12304178610189",6);
            correspondenceMap.put("12304178610202",7);
            correspondenceMap.put("12304178610237",8);
            correspondenceMap.put("12304178610173",9);
            correspondenceMap.put("12304178610198",10);
            correspondenceMap.put("12304178610168",11);
            correspondenceMap.put("12304178610180",12);
            correspondenceMap.put("12304178610178",13);
            correspondenceMap.put("12304178610172",14);
            correspondenceMap.put("12304178610204",15);
            correspondenceMap.put("12304178610206",16);
            correspondenceMap.put("12304178610210",17);
            correspondenceMap.put("12304178610228",18);
            correspondenceMap.put("12304178610229",19);
            correspondenceMap.put("12304178610183",20);
            correspondenceMap.put("12304178610192",21);
            correspondenceMap.put("12304178610161",22);
            correspondenceMap.put("12304178610222",23);
            correspondenceMap.put("12304178610215",24);
            correspondenceMap.put("12304178610227",25);
            correspondenceMap.put("12304178610208",26);
            correspondenceMap.put("12304178610187",27);
            correspondenceMap.put("12304178610207",28);
            correspondenceMap.put("12304178610174",29);
            correspondenceMap.put("12304178610181",30);
            correspondenceMap.put("12304178610200",31);
            correspondenceMap.put("12304070570004",32);
            correspondenceMap.put("12304070570006",33);
            correspondenceMap.put("12304178610194",34);
            correspondenceMap.put("12304178610238",35);
            correspondenceMap.put("12304178610233",36);
            correspondenceMap.put("12304070570018",37);
            correspondenceMap.put("12304178610166",38);
            correspondenceMap.put("12304178610224",39);
            correspondenceMap.put("12304178610203",40);
            correspondenceMap.put("12304070570014",41);
            correspondenceMap.put("12304178610160",42);
            correspondenceMap.put("12304178610213",43);
            correspondenceMap.put("12304070570011",44);
            correspondenceMap.put("12304070570007",45);
            correspondenceMap.put("12304178610223",46);
            correspondenceMap.put("12304070570010",47);
            correspondenceMap.put("12304070570012",48);
            correspondenceMap.put("12304070570009",49);
            correspondenceMap.put("12304178610214",50);
            correspondenceMap.put("12304178610219",51);
            correspondenceMap.put("12304178610167",52);
            correspondenceMap.put("12304178610191",53);
            correspondenceMap.put("12304178610197",54);
            correspondenceMap.put("12304178610176",55);
            correspondenceMap.put("12304178610184",56);
            correspondenceMap.put("12304178610164",57);
            correspondenceMap.put("12304178610236",58);
            correspondenceMap.put("12304178610186",59);
            correspondenceMap.put("12304178610231",60);
            correspondenceMap.put("12304178610185",61);
            correspondenceMap.put("12304178610195",62);
            correspondenceMap.put("12304178610196",63);
            correspondenceMap.put("12304178610193",64);
            correspondenceMap.put("12304178610230",65);
            correspondenceMap.put("12304178610182",66);
            correspondenceMap.put("12304178610175",67);
            correspondenceMap.put("12304178610218",68);
            correspondenceMap.put("12304178610171",69);
            correspondenceMap.put("12304178610188",70);
            correspondenceMap.put("12304178610211",71);
            correspondenceMap.put("12304178610212",72);
            correspondenceMap.put("12304178610169",73);
            correspondenceMap.put("12304178610177",74);
            correspondenceMap.put("12304178610201",75);
            correspondenceMap.put("12304178610209",76);
            correspondenceMap.put("12304178610199",77);
            correspondenceMap.put("12304178610232",78);
            correspondenceMap.put("12304178610235",79);
            correspondenceMap.put("12304178610217",80);
            correspondenceMap.put("12304178610165",81);
            correspondenceMap.put("12304178610220",82);
            correspondenceMap.put("12304178610162",83);
            correspondenceMap.put("12304178610226",84);
            correspondenceMap.put("12304178610179",85);
            correspondenceMap.put("12304178610170",86);
            correspondenceMap.put("12304070570017",87);
            correspondenceMap.put("12304070570003",88);
            correspondenceMap.put("12304070570020",89);
            correspondenceMap.put("12304070570015",90);
            correspondenceMap.put("12304047850045",91);
            correspondenceMap.put("12304047850044",92);
            correspondenceMap.put("12304070570005",93);
            correspondenceMap.put("12304070570008",94);
            correspondenceMap.put("12304070570013",95);
            correspondenceMap.put("12304070570019",96);
            correspondenceMap.put("12304070570016",97);
            correspondenceMap.put("12304178610190",98);
            // ...继续为其他机器添加对应关系

        // ...
        return correspondenceMap;
    }



}